<script setup lang="ts">
import { computed, markRaw, ref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';
import { DictEnum } from '@vben/constants';
import { $t } from '@vben/locales';
import { cloneDeep } from '@vben/utils';

import { useVbenForm, z } from '#/adapter/form';
import {
  getAttributeDetail,
  saveAttribute,
  updateAttribute,
} from '#/api/iot/product/attribute';
import { getDictOptions } from '#/utils/dict';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';

import TwoBoolFields from './custom-fieIds/two-bool-fields.vue';
import TwoIntFields from './custom-fieIds/two-int-fields.vue';

const emit = defineEmits<{ reload: [] }>();

const isUpdate = ref(false);
const title = computed(() => {
  return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});

const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    // 默认占满
    formItemClass: 'col-span-2',
    // 默认label宽度 px
    labelWidth: 80,
    // 通用配置项 会影响到所有表单项
    componentProps: {
      class: 'w-full',
    },
  },
  fieldMappingTime: [
    ['valueScope', ['min', 'max'], null],
    ['boolScope', ['trueDesc', 'falseDesc'], null],
  ],

  schema: [
    {
      label: '主键',
      fieldName: 'id',
      component: 'Input',
      dependencies: {
        show: () => false,
        triggerFields: [''],
      },
    },
    {
      label: 'blockId',
      fieldName: 'blockId',
      component: 'Input',
      dependencies: {
        show: () => false,
        triggerFields: [''],
      },
    },
    {
      label: '功能类型',
      fieldName: 'functionType',
      component: 'Select',
      rules: 'required',
      componentProps: {
        options: getDictOptions(DictEnum.IOT_FUNCTION_TYPE),
      },
    },
    {
      label: '功能名称',
      fieldName: 'name',
      component: 'Input',
      rules: 'required',
    },
    {
      label: '标识符',
      fieldName: 'identifier',
      component: 'Input',
      rules: 'required',
      componentProps: {
        disabled: isUpdate.value,
      },
      dependencies: {
        disabled(values) {
          return !!values.id;
        },
        triggerFields: ['id'],
      },
    },
    {
      label: '数据类型',
      fieldName: 'dataType',
      component: 'Select',
      rules: 'required',
      componentProps: {
        options: getDictOptions(DictEnum.IOT_PROPERTY_DATA_TYPE),
        disabled: isUpdate.value,
      },
      dependencies: {
        disabled(values) {
          return !!values.id;
        },
        triggerFields: ['id'],
      },
    },
    {
      component: markRaw(TwoIntFields),
      label: '取值范围',
      fieldName: 'valueScope',
      defaultValue: [null, null],
      disabledOnChangeListener: false,
      dependencies: {
        if(values) {
          return values.dataType === 'int32' || values.dataType === 'float';
        },
        // 只有指定的字段改变时，才会触发
        triggerFields: ['dataType'],
      },
      rules: z
        .array(z.number().optional())
        .length(2, '请填写最小值和最大值') // 确保数组长度为 2
        .refine((v) => v[0] !== undefined && v[1] !== undefined, {
          message: '请填写最小值和最大值',
        })
        .refine(
          (v) => v[0] !== undefined && v[1] !== undefined && v[0] <= v[1],
          {
            message: '最小值不能大于最大值',
          },
        ),
    },

    {
      component: markRaw(TwoBoolFields),
      label: '布尔',
      fieldName: 'boolScope',
      defaultValue: [undefined, undefined],
      disabledOnChangeListener: false,
      dependencies: {
        if(values) {
          return values.dataType === 'bool';
        },
        // 只有指定的字段改变时，才会触发
        triggerFields: ['dataType'],
      },
      rules: z
        .array(z.string().optional())
        .refine((v) => !!v[0], {
          message: '请填写布尔值',
        })
        .refine((v) => !!v[1], {
          message: '请填写布尔值',
        }),
    },

    {
      label: '精度',
      fieldName: 'scale',
      component: 'InputNumber',
      rules: 'required',
      componentProps: {
        precision: 0,
      },
      dependencies: {
        if(values) {
          return values.dataType === 'float';
        },
        // 只有指定的字段改变时，才会触发
        triggerFields: ['dataType'],
      },
    },
    {
      fieldName: 'unit',
      label: '单位',
      dependencies: {
        if(values) {
          return values.dataType === 'int32' || values.dataType === 'float';
        },
        // 只有指定的字段改变时，才会触发
        triggerFields: ['dataType'],
      },
      component: 'Input',
      componentProps: {
        precision: 0,
      },
    },
    {
      label: '数据长度',
      fieldName: 'textLength',
      component: 'InputNumber',
      rules: 'required',
      componentProps: {
        precision: 0,
      },
      dependencies: {
        if(values) {
          return values.dataType === 'text';
        },
        // 只有指定的字段改变时，才会触发
        triggerFields: ['dataType'],
      },
    },
    {
      fieldName: 'method',
      label: '读写',
      component: 'Select',
      defaultValue: 'r',
      componentProps: {
        options: [
          { label: '只读', value: 'r' },
          { label: '读写', value: 'rw' },
        ],
      },
    },
    {
      fieldName: 'sort',
      label: '排序',
      component: 'InputNumber',
      componentProps: {
        precision: 0,
      },
    },
  ],
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2',
});
const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
  {
    initializedGetter: defaultFormValueGetter(formApi),
    currentGetter: defaultFormValueGetter(formApi),
  },
);
const [BasicDrawer, drawerApi] = useVbenDrawer({
  onBeforeClose,
  onClosed: handleClosed,
  onConfirm: handleConfirm,
  onOpenChange: async (isOpen) => {
    if (!isOpen) {
      return null;
    }
    drawerApi.drawerLoading(true);

    const { id, blockId } = drawerApi.getData() as {
      blockId: string;
      id?: number | string;
    };
    isUpdate.value = !!id;

    if (blockId) {
      await formApi.setValues({ blockId, valueScope: [], boolScope: [] });
    }
    if (isUpdate.value && id) {
      const record = await getAttributeDetail(id);
      record.valueScope = [record.min, record.max];

      record.boolScope = [record.trueDesc, record.falseDesc];
      await formApi.setValues(record);
    }
    await markInitialized();
    drawerApi.drawerLoading(false);
  },
});
async function handleConfirm() {
  try {
    drawerApi.drawerLoading(true);
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    const data = cloneDeep(await formApi.getValues());
    await (isUpdate.value ? updateAttribute(data) : saveAttribute(data));
    emit('reload');
    resetInitialized();
    drawerApi.drawerLoading(false);
    drawerApi.close();
  } catch (error) {
    console.error(error);
  } finally {
    drawerApi.drawerLoading(false);
  }
}

async function handleClosed() {
  await formApi.resetForm();
  resetInitialized();
}
</script>

<template>
  <BasicDrawer :close-on-click-modal="false" :title="title" class="w-[650px]">
    <BasicForm />
  </BasicDrawer>
</template>
